package com.xyht.sca_s.student_manage_system.modules.user.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.CacheUtil;
import com.xyht.sca_s.student_manage_system.common.util.PinYinUtil;
import com.xyht.sca_s.student_manage_system.modules.user.entity.*;
import com.xyht.sca_s.student_manage_system.modules.user.entity.req.SmsApplicationUpdateReq;
import com.xyht.sca_s.student_manage_system.modules.user.entity.resp.*;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.*;
import com.xyht.sca_s.student_manage_system.modules.user.service.SmsApplicationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.user.constant.AppUpDownConstant.APP_UP;
import static com.xyht.sca_s.student_manage_system.modules.user.constant.commonConstant.*;

/**
 * <p>
 * 界面应用 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2022-12-24
 */
@Service
public class SmsApplicationServiceImpl extends ServiceImpl<SmsApplicationMapper, SmsApplication> implements SmsApplicationService {
    @Autowired
    private SmsApplicationMapper smsApplicationMapper;
    @Autowired
    private SmsUserMapper smsUserMapper;
    @Autowired
    private CacheUtil cacheUtil;
    @Autowired
    private SmsRoleApplicationRelationMapper smsRoleApplicationRelationMapper;
    @Autowired
    private SmsApplicationCollectionMapper smsApplicationCollectionMapper;
    @Autowired
    private SmsApplicationClickMapper smsApplicationClickMapper;
    @Autowired
    private SmsApplicationPointServiceImpl smsApplicationPointService;
    @Autowired
    private SmsApplicationPointMapper smsApplicationPointMapper;
    @Autowired
    private SmsApplicationTypeMapper smsApplicationTypeMapper;
    @Autowired
    private PinYinUtil pinYinUtil;
    @Autowired
    private SmsApplicationAndTypeMpjMapper smsApplicationAndTypeMpjMapper;

    @Override
    public ResponseResult getAppList(Integer app_client, String search_str, String type_id) {
        if (isNullOrEmpty(app_client)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        MPJLambdaWrapper<SmsApplication> mpjLambdaWrapper = new MPJLambdaWrapper<>();
        mpjLambdaWrapper
                .selectAll(SmsApplication.class)
                .selectAs(SmsApplicationType::getId, "typeId")
                .selectAs(SmsApplicationType::getTypeName, "typeName")
                .selectAs(SmsApplicationType::getTypeSpell, "typeSpell")
                .leftJoin(SmsApplicationType.class, SmsApplicationType::getId, SmsApplication::getAppTypeId)
                .eq(SmsApplication::getAppClient, app_client)
                .orderByAsc(SmsApplicationType::getTypeSpell)
                .orderByAsc(SmsApplication::getAppSpell);
        if (!isNullOrEmpty(search_str)) {
            mpjLambdaWrapper.and(wrapper -> {
                wrapper.like(SmsApplication::getAppName, search_str);
            });
        }
        if (!isNullOrEmpty(type_id)) {
            mpjLambdaWrapper.eq(SmsApplication::getAppTypeId, type_id);
        }

        List<SmsApplicationAndTypeResp> list = smsApplicationAndTypeMpjMapper.selectJoinList(SmsApplicationAndTypeResp.class,
                mpjLambdaWrapper);


//        QueryWrapper<SmsApplicationType> appTypeQueryWrapper = new QueryWrapper<>();
//        appTypeQueryWrapper.lambda()
//                .orderByAsc(SmsApplicationType::getTypeSpell);
////        if (!isNullOrEmpty(search_str)) {
////            appTypeQueryWrapper.lambda().like(SmsApplicationType::getTypeName, search_str);
////        }
//        List<SmsApplicationInfoByTypeResp> list = smsApplicationTypeMapper.selectList(appTypeQueryWrapper)
//                .stream()
//                .map(appType -> {
//                    SmsApplicationInfoByTypeResp smsApplicationInfoByTypeResp =
//                            new SmsApplicationInfoByTypeResp();
//                    BeanUtils.copyProperties(appType, smsApplicationInfoByTypeResp);
//
//                    QueryWrapper<SmsApplication> appQueryWrapper = new QueryWrapper<>();
//                    appQueryWrapper.lambda()
//                            .eq(SmsApplication::getAppClient, app_client)
//                            .eq(SmsApplication::getAppTypeId, appType.getId())
//                            .orderByAsc(SmsApplication::getAppSpell);
//                    if (!isNullOrEmpty(search_str)) {
//                        appQueryWrapper.lambda().like(SmsApplication::getAppName, search_str);
//                    }
//
//                    List<SmsApplicationResp> applicationRespList = smsApplicationMapper.selectList(appQueryWrapper)
//                            .stream()
//                            .map(appInfo -> {
//                                SmsApplicationResp smsApplicationResp = new SmsApplicationResp();
//                                BeanUtils.copyProperties(appInfo, smsApplicationResp);
//                                return smsApplicationResp;
//                            })
//                            .collect(Collectors.toList());
//
//                    smsApplicationInfoByTypeResp.setApplicationList(applicationRespList);
//                    return smsApplicationInfoByTypeResp;
//                })
//                .filter(appType->{
//                    boolean bl = appType.getTypeName().contains(search_str);
//                    if (appType.getApplicationList().size()>0){
//                        return true;
//                    }else{
//                        return bl;
//                    }
//                })
//                .collect(Collectors.toList());
        return CommonResult.success(list);
    }

    @Override
    public ResponseResult userUseGetAppList(String user_id, Integer app_client, Integer is_collection, String search_str) {
        List<SmsApplicationInfoByTypeResp> respList = new ArrayList<>();
        if (isNullOrEmpty(app_client)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsUser user = smsUserMapper.selectById(user_id);
        if (user == null) {
            return CommonResult.failed(CommonCodeEnum.USER_NOT_EXIST);
        }

        List<String> roleList = cacheUtil.getRoleList(user_id);
        List<String> appList = new ArrayList<>();
        if (roleList.size() > 0) {
            //获取用户角色应用列表
            List<SmsRoleApplicationRelation> roleApplicationRelationList = smsRoleApplicationRelationMapper.selectList(
                    new QueryWrapper<SmsRoleApplicationRelation>()
                            .lambda().select(SmsRoleApplicationRelation::getAppId).in(SmsRoleApplicationRelation::getRoleId, roleList).groupBy(SmsRoleApplicationRelation::getAppId));
            appList = roleApplicationRelationList.stream().map(SmsRoleApplicationRelation::getAppId).collect(Collectors.toList());
        } else {
            return CommonResult.success(respList);
        }

        QueryWrapper<SmsApplication> queryWrapper = new QueryWrapper<>();
        if (appList.size() > 0) {
            queryWrapper.lambda().in(SmsApplication::getId, appList);
        } else {
            return CommonResult.success(respList);
        }
        queryWrapper.lambda().eq(SmsApplication::getAppClient, app_client)
                .eq(SmsApplication::getUpDown, APP_UP);
        //获取上架应用列表
        List<SmsApplication> smsApplicationList = smsApplicationMapper.selectList(queryWrapper);
        List<Integer> appIDList = smsApplicationList.stream().map(SmsApplication::getId).collect(Collectors.toList());
        if (appIDList.size() < 1) {
            return CommonResult.success(respList);
        }

        List<String> collectionAppTypeList;
        //获取收藏应用
        List<SmsApplicationCollection> collectionList = smsApplicationCollectionMapper.selectList(new QueryWrapper<SmsApplicationCollection>()
                .lambda()
                .eq(SmsApplicationCollection::getUserId, user_id));
        collectionAppTypeList = collectionList.stream().map(SmsApplicationCollection::getAppType).collect(Collectors.toList());

        List<String> finalCollectionAppTypeList = collectionAppTypeList;


        //获取分类列表
        respList = smsApplicationTypeMapper.selectList(new QueryWrapper<SmsApplicationType>()
                .lambda()
                .orderByAsc(SmsApplicationType::getTypeSpell))
                .stream()
                .map(smsApplicationType -> {
                    SmsApplicationInfoByTypeResp typeResp = new SmsApplicationInfoByTypeResp();
                    BeanUtils.copyProperties(smsApplicationType, typeResp);

//                    QueryWrapper<SmsApplication> appQueryWrapper = new QueryWrapper<>();
//                    appQueryWrapper.lambda()
//                            .in(SmsApplication::getId, appIDList)
//                            .eq(SmsApplication::getAppClient, app_client)
//                            .eq(SmsApplication::getAppTypeId, typeResp.getId())
//                            .orderByAsc(SmsApplication::getAppSpell);
//                    if (!isNullOrEmpty(search_str)) {
//                        appQueryWrapper.lambda().like(SmsApplication::getAppName, search_str);
//                    }

                    List<SmsApplicationResp> appRespList = smsApplicationMapper.selectList(new QueryWrapper<SmsApplication>()
                            .lambda()
                            .in(SmsApplication::getId, appIDList)
                            .eq(SmsApplication::getAppClient, app_client)
                            .eq(SmsApplication::getAppTypeId, typeResp.getId())
                            .orderByAsc(SmsApplication::getAppSpell))
                            .stream()
                            .filter(smsApplication -> {
                                if (is_collection != null && is_collection == 1) {
                                    if (!finalCollectionAppTypeList.contains(smsApplication.getAppType())) {
                                        return false;
                                    }
                                }
                                return true;
                            })
                            .map(smsApplication -> {
                                SmsApplicationResp smsApplicationResp = new SmsApplicationResp();
                                BeanUtils.copyProperties(smsApplication, smsApplicationResp);

                                if (finalCollectionAppTypeList.contains(smsApplication.getAppType())) {
                                    smsApplicationResp.setIsCollection(APP_COLLECTION_TRUE);
                                } else {
                                    smsApplicationResp.setIsCollection(APP_COLLECTION_FALSE);
                                }

                                if (!isNullOrEmpty(smsApplicationResp.getAppType())) {
                                    Integer collectionCount = smsApplicationCollectionMapper.selectCount(new QueryWrapper<SmsApplicationCollection>()
                                            .lambda()
                                            .eq(SmsApplicationCollection::getAppType, smsApplicationResp.getAppType()));
                                    smsApplicationResp.setCollectionNum(collectionCount);

                                    Integer clickCount = smsApplicationClickMapper.selectCount(new QueryWrapper<SmsApplicationClick>()
                                            .lambda()
                                            .eq(SmsApplicationClick::getAppType, smsApplicationResp.getAppType()));
                                    smsApplicationResp.setClickNum(clickCount);

//                SmsApplicationPoint smsApplicationPoint
                                    List<Map<String, Object>> mapList = smsApplicationPointMapper.selectMaps(new QueryWrapper<SmsApplicationPoint>()
                                            .select("count(*) as count , sum(point) as sum")
                                            .lambda()
                                            .eq(SmsApplicationPoint::getAppType, smsApplicationResp.getAppType()));

                                    Map<String, Object> pointMap = mapList.get(0);
                                    SmsApplicationPointResp smsApplicationPointResp = JSONObject.parseObject(JSONObject.toJSONString(pointMap), SmsApplicationPointResp.class);

                                    Integer pointNum = smsApplicationPointResp.getCount();
                                    Double point = DEFAULT_POINT;
                                    if (pointNum > 0) {
                                        point = Math.floor((smsApplicationPointResp.getSum() / pointNum) * 10) / 10;
                                    }
                                    smsApplicationResp.setPointNum(pointNum);
                                    smsApplicationResp.setAveragePoint(point);
                                } else {
                                    smsApplicationResp.setCollectionNum(DEFAULT_COLLECTION);
                                    smsApplicationResp.setClickNum(DEFAULT_CLICK);
                                    smsApplicationResp.setAveragePoint(DEFAULT_POINT);
                                }
                                return smsApplicationResp;
                            })
                            .collect(Collectors.toList());
                    typeResp.setApplicationList(appRespList);

                    return typeResp;
                })
                .filter(respApp -> respApp.getApplicationList().size() > 0)
                .collect(Collectors.toList());
        return CommonResult.success(respList);
    }

    @Override
    public ResponseResult updateApp(SmsApplicationUpdateReq smsAppReq) {
        if (isNullOrEmpty(smsAppReq.getId()) || isNullOrEmpty(smsAppReq.getUpDown())
                || isNullOrEmpty(smsAppReq.getAppName()) || isNullOrEmpty(smsAppReq.getAppClient())
                || isNullOrEmpty(smsAppReq.getAppTypeId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsApplication smsApplication = smsApplicationMapper.selectById(smsAppReq.getId());
        if (smsApplication == null) {
            return CommonResult.failed(CommonCodeEnum.APP_NOT_EXIST);
        }
//        if (!smsApplication.getAppName().equals(smsAppReq.getAppName())) {
//            SmsApplication appName = smsApplicationMapper.selectOne(new QueryWrapper<SmsApplication>()
//                    .lambda().eq(SmsApplication::getAppName, smsAppReq.getAppName()));
//            if (appName != null) {
//                return CommonResult.failed(CommonCodeEnum.APP_NAME_EXIST);
//            }
//        }

        String spellStr = pinYinUtil.getHanZiPY(smsAppReq.getAppName());
        SmsApplication updateApp = new SmsApplication();
        BeanUtils.copyProperties(smsAppReq, updateApp);
        updateApp.setAppSpell(spellStr);
        smsApplicationMapper.updateById(updateApp);
        return CommonResult.success();
    }

    @Override
    public ResponseResult addApp(SmsApplicationUpdateReq smsAppReq) {
        if (isNullOrEmpty(smsAppReq.getUpDown()) || isNullOrEmpty(smsAppReq.getAppName())
                || isNullOrEmpty(smsAppReq.getAppClient()) || isNullOrEmpty(smsAppReq.getAppPath())
                || isNullOrEmpty(smsAppReq.getAppTypeId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

//        SmsApplication smsApplication = smsApplicationMapper.selectOne(new QueryWrapper<SmsApplication>()
//                .lambda().eq(SmsApplication::getAppName, smsAppReq.getAppName())
//                .eq(SmsApplication::getAppClient, smsAppReq.getAppClient()));
//        if (smsApplication != null) {
//            return CommonResult.failed(CommonCodeEnum.APP_CLIENT_NAME_EXIST);
//        }

        String spellStr = pinYinUtil.getHanZiPY(smsAppReq.getAppName());
        SmsApplication addApplication = new SmsApplication();
        BeanUtils.copyProperties(smsAppReq, addApplication);
        addApplication.setAppSpell(spellStr);
        smsApplicationMapper.insert(addApplication);
        return CommonResult.success();
    }

    @Override
    public ResponseResult appCollection(String user_id, SmsApplicationCollection collection) {
        if (isNullOrEmpty(collection.getAppType())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsApplicationCollection smsApplicationCollection = new SmsApplicationCollection();
        smsApplicationCollection.setUserId(user_id);
        smsApplicationCollection.setAppType(collection.getAppType());
        smsApplicationCollectionMapper.insert(smsApplicationCollection);
        return CommonResult.success();
    }

    @Override
    public ResponseResult appCollectionCancel(String user_id, SmsApplicationCollection collection) {
        if (isNullOrEmpty(collection.getAppType())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        QueryWrapper<SmsApplicationCollection> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(SmsApplicationCollection::getAppType, collection.getAppType())
                .eq(SmsApplicationCollection::getUserId, user_id);
        smsApplicationCollectionMapper.delete(queryWrapper);
        return CommonResult.success();
    }

    @Override
    public ResponseResult appClick(String user_id, SmsApplicationClick click) {
        if (isNullOrEmpty(click.getAppType())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsApplicationClick smsApplicationClick = new SmsApplicationClick();
        smsApplicationClick.setAppType(click.getAppType());
        smsApplicationClick.setUserId(user_id);
        smsApplicationClickMapper.insert(smsApplicationClick);
        return CommonResult.success();
    }

    @Override
    public ResponseResult appPoint(String user_id, SmsApplicationPoint point) {
        if (isNullOrEmpty(point.getAppType()) || isNullOrEmpty(point.getPoint())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        if (point.getPoint() < 1 || point.getPoint() > 5) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsApplicationPoint resultPoint = smsApplicationPointMapper.selectOne(new QueryWrapper<SmsApplicationPoint>()
                .lambda()
                .eq(SmsApplicationPoint::getUserId, user_id)
                .eq(SmsApplicationPoint::getAppType, point.getAppType()));
        //没有添加 有就更新
        if (resultPoint == null || resultPoint.getUserId() == null) {
            SmsApplicationPoint smsApplicationPoint = new SmsApplicationPoint();
            smsApplicationPoint.setPoint(point.getPoint());
            smsApplicationPoint.setAppType(point.getAppType());
            smsApplicationPoint.setUserId(user_id);
            smsApplicationPointMapper.insert(smsApplicationPoint);
        } else {
            SmsApplicationPoint smsApplicationPoint = new SmsApplicationPoint();
            smsApplicationPoint.setPoint(point.getPoint());
            smsApplicationPointMapper.update(smsApplicationPoint, new QueryWrapper<SmsApplicationPoint>()
                    .lambda()
                    .eq(SmsApplicationPoint::getUserId, user_id)
                    .eq(SmsApplicationPoint::getAppType, point.getAppType()));
        }
        return CommonResult.success();
    }
}
